﻿<template>
  <el-dialog draggable :title='dialogSelectTitle' v-model='dialogSelectVisible' width='55%' :before-close="handleClose"
    :close-on-press-escape='false' :close-on-click-modal='false'>
    <FormBase>
      <QueryBase :showSearch="false" style="width: 95%;">
        <!-- 表格部分 -->
        <div class='page_tableContent'>
          <el-table :data='table.tableData' row-key="function_no" default-expand-all height="400" style='width:100%'
            stripe :border="true" @select-all="handleSelectAll" @select='handleSelect' ref='myTable'>
            <el-table-column :align="index === 0 ? '' : 'center'" show-overflow-tooltip
              v-for='(item, index) in table.tableColumn' :key='item.indexName' :label='item.text'>
              <template #default='scope'>
                <span>{{ scope.row[item.indexName] }}</span>
              </template>
            </el-table-column>
            <el-table-column :label="t('权限')">
              <template #default='scope'>
                <el-checkbox-group v-model="scope.row.actions">
                  <el-checkbox v-for="(item, index) in actionOptions" :key="item.value" :label="item.label"
                    :value="item.value" />
                </el-checkbox-group>
              </template>
            </el-table-column>
            <el-table-column type="selection" :reserve-selection="true" width="55"></el-table-column>
          </el-table>
        </div>
      </QueryBase>
      <template #submit>
        <el-button type="primary" size="large" @click='handleSubmit'>确 定</el-button>
        <el-button size="large" @click="$emit('giveUpFunc')">取 消</el-button>
      </template>
    </FormBase>
  </el-dialog>
</template>

<script lang="ts" setup>
import { getActionOptions, getAllMenus, getRoleAuth, getRoles } from '@/api/authorization';
import comFunc from '@/common/comFunc';
import elHelper from '@/common/elHelper';
import { defineProps, ref, watch, defineEmits, reactive, onMounted } from 'vue'
import QueryBase from '@/components/layout/QueryBase.vue';
import FormBase from '@/components/layout/FormBase.vue';
import { t } from '@/common/locale'
const props = defineProps({
  funcDialog: {
    type: Boolean,
    default: false
  },
  roles: {
    type: String,
    default: ''
  }
})
const emits = defineEmits(['giveUpFunc', 'sureFuncSelect'])

const dialogSelectTitle = ref('')
const dialogSelectVisible = ref(false)
const actionOptions = ref<any[]>([])
const table = reactive({
  tableData: [] as any[],
  tableColumn: [
    {
      text: '功能名称',
      indexName: 'function_name'
    },
    {
      text: '功能编号',
      indexName: 'function_no'
    }
  ]
})
const myTable = ref()
const multipleSelection = ref<any[]>([])
const totalFuncs = ref<any[]>([])
const roleFuncs = ref<any[]>([])
const functionActions = ref<any[]>([])

onMounted(() => {
  getActions()
})

const handleSelectAll = (val: any) => {
  if (val.length === totalFuncs.value.length || val.length === table.tableData.length) {
    val.forEach(item => {
      handleSelect(val, item)
    })
  } else {
    multipleSelection.value.forEach(item => {
      item.actions = []
    })
    myTable.value.clearSelection()
    multipleSelection.value = []
  }
}
const setSelected = (row) => {
  row.actions = 'view,edit'.split(',')
  if (!multipleSelection.value.find(w => w.function_no === row.function_no)) {
    multipleSelection.value.push(row)
  }
}
const removeSelected = (row) => {
  row.actions = []
  const index = multipleSelection.value.findIndex(w => w.function_no === row.function_no)
  if (index >= 0) {
    multipleSelection.value.splice(index, 1)
  }
}
const handleSelect = (val, row) => {
  // 点击是选中时
  if (val.length && val.indexOf(row) !== -1) {
    // 当有父元素时，要求也选中
    if (row.p_functionno) {
      let parentRow = getParents(row.p_functionno)
      if (!parentRow) {
        return
      }
      selectParent(parentRow)
      myTable.value.toggleRowSelection(parentRow, true)
      setSelected(parentRow)
    }
    // 当有子元素时，子元素全选
    if (row.children && row.children.length) {
      row.children.forEach(val => {
        selectChild(val)
      })
    }
    // 本身需要选中
    setSelected(row)
    // 点击是取消选择时
  } else {
    // 当有父元素时，需判断该父元素下的子元素是否选中，如果没有选中，则该父元素取消选中
    if (row.p_functionno) {
      let count = 0
      let parentRow = getParents(row.p_functionno)
      if (!parentRow) {
        return
      }
      parentRow.children.forEach(vals => {
        if (val.indexOf(vals) === -1) {
          count++
        }
      })
      if (count === parentRow.children.length) {
        myTable.value.toggleRowSelection(parentRow, false)
        removeSelected(parentRow)
      }
      unSelectParent(multipleSelection, parentRow)
    }
    // 当有子元素时，子元素取消选中
    if (row.children && row.children.length) {
      row.children.forEach(val => {
        unSelectChild(val)
      })
    }
    // 本身需要取消选中
    removeSelected(row)
  }
  // multipleSelection = val
}
const selectParent = (parentRow) => {
  if (parentRow.p_functionno) {
    let parentRows = getParents(parentRow.p_functionno)
    selectParent(parentRows)
    myTable.value.toggleRowSelection(parentRows, true)
    setSelected(parentRows)
  }
}
const selectChild = (checkVal) => {
  if (checkVal.children && checkVal.children.length) {
    checkVal.children.forEach(val => {
      selectChild(val)
    })
  }
  myTable.value.toggleRowSelection(checkVal, true)
  setSelected(checkVal)
}
// 判断取消的选框是否有子菜单,有就取消选择
const unSelectChild = (checkVal) => {
  if (checkVal.children && checkVal.children.length) {
    checkVal.children.forEach(val => {
      unSelectChild(val)
    })
  }
  myTable.value.toggleRowSelection(checkVal, false)
  removeSelected(checkVal)
}
const unSelectParent = (selectedVal, parentRow) => {
  if (parentRow.p_functionno) {
    let count = 0
    let parentRows = getParents(parentRow.p_functionno)
    parentRows.children.forEach(vals => {
      if (selectedVal.indexOf(vals) === -1) {
        count++
      }
    })
    if (count === parentRows.children.length) {
      myTable.value.toggleRowSelection(parentRows, false)
      removeSelected(parentRows)
    }
    unSelectParent(multipleSelection.value, parentRows)
  }
}
const getParents = (pCode): any => {
  let parentRow = ''
  let getParent = false
  if (table.tableData.length) {
    table.tableData.forEach(val => {
      if (val.functionno === pCode) { // 先判断该元素是不是需要获取的父元素,不是的话就在其子元素中寻找
        parentRow = val
        getParent = true
      } else {
        if (val.children.length) {
          let hadGet = getLastParent(pCode, val.children)
          if (hadGet) {
            parentRow = hadGet
            getParent = true
          }
        }
      }
    })
  }
  if (getParent) {
    return parentRow
  }
}
const getLastParent = (pCode, childrenArray) => {
  let parentRow: string | undefined = ''
  for (let i = 0; i < childrenArray.length; i++) {
    if (childrenArray[i].functionno === pCode) {
      parentRow = childrenArray[i]
      return parentRow
    } else {
      if (childrenArray[i].children.length) {
        parentRow = getLastParent(pCode, childrenArray[i].children)
        if (parentRow) {
          return parentRow
        }
      }
    }
  }
}
const getRoleInfo = async () => {
  if (props.roles) {
    const re = await getRoleAuth(props.roles)

    if (re.isSuccess) {
      roleFuncs.value = re.data.function
      functionActions.value = re.data.functionActions
      multipleSelection.value = []
      getFunctions()
    }
  }
}
const getFunctions = async () => {
  const re = await getAllMenus()

  if (re.isSuccess) {
    totalFuncs.value = re.data
    // 只展示的功能权限---部分功能不展示,超级管理员展示所有
    let showData: any[] = []
    re.data.forEach(item => {
      item.actions = getFunctionActions(item.function_no)
      showData.push(item)

    })
    // 将数据结构转化为树形结构
    table.tableData = comFunc.$toTree(showData, true)
    myTable.value.clearSelection()
    if (roleFuncs.value.length) {
      roleFuncs.value.forEach(val => {
        getSelectedFuns(table.tableData, val.function_no)
      })
    }
  }
}
const getSelectedFuns = (funcData, funno) => {
  if (funcData.length) {
    funcData.forEach(row => {
      if (row.function_no === funno) {
        myTable.value.toggleRowSelection(row, true)
        setSelected(row)
      } else {
        if (row.children && row.children.length) {
          getSelectedFuns(row.children, funno)
        }
      }
    });
  }
}
const getActions = async () => {
  let re = await getActionOptions()
  if (re.isSuccess) {
    actionOptions.value = re.data
  }
}
const handleClose = () => {
  emits('giveUpFunc')
}
const handleSubmit = () => {
  emits('sureFuncSelect', multipleSelection.value, totalFuncs.value)

}
const getFunctionActions = (function_no: any) => {
  const aitem = functionActions.value.find(w => w.function_no === function_no)
  if (aitem) {
    return aitem.actions.split(',')
  } else {
    return []
  }
}
watch(() => props.funcDialog, (val) => {
  dialogSelectVisible.value = val
  if (val) {
    // 将数据还原
    dialogSelectTitle.value = '功能授权'
    getRoleInfo()
  }
})

</script>

<style scoped lang='scss'>
.table_toggleBtn {
  display: inline-block;
  width: 18px;
  height: 100%;
  margin-left: 20px;
  cursor: pointer;

  i {
    font-size: 18px;
    vertical-align: -1px;
  }
}

.table_trSpace {
  display: inline-block;
  width: 22px;
  height: 10px;
}
</style>
